Safe Navigation
For Member Access
Accessing deeply nested fields which can potentially be nil
was problematic, because you'd need an unreasonable amount of guard clauses to prevent an "attempt to index nil" error. Pluto now offers this syntax:
Basic Usagepluto
local person = {name = "Alice"}local pet_name = person.pet?.name
In this example, person.pet
is nil. However, this does not throw an "attempt to index nil" error. pet_name
is simply set to nil
.
Practical Usagepluto
-- Pretend userConfig is parsed from a JSON file, or something.--- Returning the user's preferred color, or Red if they have no preferred color.local function get_color()return userConfig.colors?.preferred ?? "Red"endprint(get_color())
In this example, we also use the null coalescing operator ??
.
These cannot be used for statements, like a?.b?.c = 0
. They're only valid as expressions.
Safe Navigation (for member access) was written by Sven Olsen.
For Method Calls
Similarly, if you want to have optional hook functions, you can use safe method calls instead of writing conditionals:
Lua Waypluto
if self.onEvent thenself:onEvent(event)end
Pluto Waypluto
self:onEvent?(event)
You can also check if the left-hand side of :
is not nil:
pluto
object?:onEvent(event) -- 'object' may be nilobject?:onEvent?(event) -- 'object' and 'object.onEvent' may be nil
Note that this feature will truncate multiple return values if they're not used as part of a fixed assignment:
pluto
function myfunc()return 1, 2endlocal a, b, c = _G:myfunc?()print(a, b, c) --> 1 2 nilprint(_G:myfunc?()) --> 1